import { TouchPanelBase } from "./TouchPanel.generated";

const { regClass } = Laya;

@regClass()
export class TouchPanel extends TouchPanelBase {
    /** 上边距 */
    public readonly marginTop:number = 117;
    /** 缩放适配 */
    public marginSc:number = 1;
    nowEventTouch: Laya.Event;
    _ctrlTyoe: ETouchMoveType = ETouchMoveType.none;

    /** 上一帧的鼠标位置 X */
    lastMouseX: number = 0;
    /** 上一帧的鼠标位置 Y */
    lastMouseY: number = 0;
    /** 上一帧的两指间的距离 */
    lastLength: number = 0;

    nowScale: number = 1.5;
    arrTouchLength = -1;
    actLoadOver: Function;
    /** 图片加载完成 */
    imgLoadOver:boolean = false;

    onAwake(): void {
        this.on(Laya.Event.MOUSE_DOWN, this, this.onTouchDown)
        this.on(Laya.Event.MOUSE_MOVE, this, this.onTouchMove)
        this.on(Laya.Event.MOUSE_OUT, this, this.onTouchUp)
        this.on(Laya.Event.MOUSE_UP, this, this.onTouchUp)
    }
    onDestroy(): void {
        this.off(Laya.Event.MOUSE_DOWN, this, this.onTouchDown)
        this.off(Laya.Event.MOUSE_MOVE, this, this.onTouchMove)
        this.off(Laya.Event.MOUSE_OUT, this, this.onTouchUp)
        this.off(Laya.Event.MOUSE_UP, this, this.onTouchUp)
    }

    get ctrlTyoe() { return this._ctrlTyoe }
    set ctrlTyoe(v: ETouchMoveType) {
        this._ctrlTyoe = v;
        switch (v) {
            case ETouchMoveType.none:
                break;
            case ETouchMoveType.move:
                this.lastMouseX = this.nowEventTouch.touches[0].pos.x;
                this.lastMouseY = this.nowEventTouch.touches[0].pos.y;
                break;
            case ETouchMoveType.scale:
                this.lastLength = this.getDistance(this.nowEventTouch.touches)
                break;
        }
    }

    /**
     * 缩放倍率是 1~2
     * 小图按照1倍去缩放
     * 中等图不缩放
     * 大图按照2倍去缩放
     */
    public loadTexture(path: string, actLoadOver: ()=>void) {
        this.actLoadOver = actLoadOver;
        this.imgLoadOver = false;
        this.nowScale = 1;
        this.ImgMain.loadImage(path, new Laya.Handler(this, this.LoadOver))
    }


    public getSceneXY(x: number, y: number) {
        // console.log("传入X",x,"位置",this.BoxCtrl.x,"屏幕大小",this.BoxPanel.width);
        return {
            x: (x * this.nowScale - Math.abs(this.BoxCtrl.x)),
            y: (y * this.nowScale - Math.abs(this.BoxCtrl.y))
        }
    }

    public getTexture(config:any):Laya.Texture {
        if (!config) { return undefined; }
        if (!this.imgLoadOver) { return undefined; }
        let rt2d = this.ImgMain.drawToRenderTexture2D(config.w*this.marginSc,config.h*this.marginSc, -config.x*this.marginSc, -config.y*this.marginSc)
        let tex = new Laya.Texture(rt2d, Laya.Texture.INV_UV); 
        return tex;
    }
    public addDifferent(obj: Laya.UIComponent) {
        this.BoxCtrl.addChild(obj);
    } 


    private onTouchDown(e: Laya.Event) {
        this.nowEventTouch = e;
        this.arrTouchLength = e.touches.length;
        if (e.touches.length == 1 || e.touches.length > 2) {
            console.log("单指移动");
            this.ctrlTyoe = ETouchMoveType.move;
        } else if (e.touches.length == 2) {
            this.ctrlTyoe = ETouchMoveType.scale;
        }
    }
    private onTouchMove(e: Laya.Event) {
        this.nowEventTouch = e;
        if (this.arrTouchLength == 2 && e.touches.length == 1) {
            this.ctrlTyoe = ETouchMoveType.move;
        }
        if (this.arrTouchLength > 2 && e.touches.length == 2) {
            this.ctrlTyoe = ETouchMoveType.scale;
        }
        // 记录每一帧的触摸点数
        if (this.arrTouchLength != -1) {
            this.arrTouchLength = e.touches.length;
        }

        if (this.ctrlTyoe == ETouchMoveType.move) {
            const moveX = e.touches[0].pos.x - this.lastMouseX;
            const moveY = e.touches[0].pos.y - this.lastMouseY;

            this.boxCtrlMoveTo(moveX, moveY);
            this.ctrlTyoe = ETouchMoveType.move;
        } else if (this.ctrlTyoe == ETouchMoveType.scale) {
            let offset = (this.getDistance(e.touches) - this.lastLength) * 0.003;
            // 缩放变更
            this.nowScale += offset;
            if (this.nowScale > 2) {
                this.nowScale = 2
                offset = 0;
            } else if (this.nowScale < 1) {
                this.nowScale = 1
                offset = 0;
            }
            if (this.BoxCtrl.width * this.nowScale < this.BoxPanel.width) {
                console.log("限制继续缩小");
                this.nowScale  -= offset;
                return;
            }
            if(this.BoxCtrl.height * this.nowScale < this.BoxPanel.height){
                console.log("限制继续缩小");
                this.nowScale  -= offset;
                return;
            }
            console.log("缩放变更", this.nowScale);
            
            // // 计算缩放中心点
            const pX = (-this.BoxCtrl.x + this.BoxPanel.width / 2) / (this.BoxCtrl.width * this.nowScale);
            const pY = (-this.BoxCtrl.y + this.BoxPanel.width / 2) / (this.BoxCtrl.height * this.nowScale);
            const moveX = -offset * pX * this.BoxCtrl.width
            const moveY = -offset * pY * this.BoxCtrl.height
            this.boxCtrlMoveTo(moveX, moveY);
            
            this.BoxCtrl.scale(this.nowScale, this.nowScale);
            this.ctrlTyoe = ETouchMoveType.scale;
        }
    }

    private onTouchUp(e: Laya.Event) {
        this.nowEventTouch = e;

        if (e.touches.length <= 1) {
            this.ctrlTyoe = ETouchMoveType.none;
            this.arrTouchLength = -1;
        }
    }

    private LoadOver() {
        this.imgLoadOver = true; 
        console.log("LoadOver 图片加载完成");

        const minW = this.BoxPanel.width * 1.2;
        const minH = this.BoxPanel.height * 1.2;

        /** 需要变大 */
        let useToLargen = false;
        /** 需要缩小 */
        let useToLessen = false;
        if (this.ImgMain.texture.sourceWidth > minW && this.ImgMain.texture.sourceHeight > minH) {
            // 宽高都比最大值大，需要进行缩小适配
            useToLessen = true;
        } else if (this.ImgMain.texture.sourceWidth < minW || this.ImgMain.texture.sourceHeight < minH) {
            // 宽高其中一个比最小值小，需要进行放大适配
            useToLargen = true;
        }

        /** 缩放比例 */
        this.marginSc = 1;
        if (useToLargen) {
            console.log("需要放大");
            // 跟进宽高比的不同选择不同的缩放策略
            // k(宽)g(高)b(比)
            // 1：1 = 1
            const kgbBox = this.BoxPanel.width / this.BoxPanel.height;
            // 16/9 > 1 按高适配
            // 9/16 < 1 按宽适配
            const kgbImg = this.ImgMain.texture.sourceWidth / this.ImgMain.texture.sourceHeight;
            if (kgbImg > kgbBox) {
                // 按高适配
                this.marginSc  = minH / this.ImgMain.texture.sourceHeight;
            } else {
                // 按宽适配
                this.marginSc  = minW / this.ImgMain.texture.sourceWidth;
            }
        } else if (useToLessen) {
            console.log("需要缩小");
            if (this.ImgMain.texture.sourceWidth > this.ImgMain.texture.sourceHeight) {
                // 宽 > 高
                // 按高适配
                this.marginSc  = minH / this.ImgMain.texture.sourceHeight;
            } else {
                // 按宽适配
                this.marginSc  = minW / this.ImgMain.texture.sourceWidth;
            }

        } else {
            console.log("无需缩放。正常展示");
            this.marginSc  = 1;
        }

        /** 图片太小就对其进行放大使其可以拖拽 */
        if (this.marginSc * this.ImgMain.texture.sourceHeight < this.BoxPanel.height*1.1) {
            this.marginSc = this.BoxPanel.height*1.1 / this.ImgMain.texture.sourceHeight;
        }
        /** 图片太小就对其进行放大使其可以拖拽 */
        if (this.marginSc * this.ImgMain.texture.sourceWidth < this.BoxPanel.width*1.1) {
            this.marginSc = this.BoxPanel.width*1.1 / this.ImgMain.texture.sourceWidth;
        }

        this.BoxCtrl.height = this.marginSc  * this.ImgMain.texture.sourceHeight;
        this.BoxCtrl.width = this.marginSc  * this.ImgMain.texture.sourceWidth;
        this.BoxCtrl.scale(this.nowScale, this.nowScale);
        console.log("this.BoxCtrl=>",this.nowScale,this.BoxCtrl.height,this.BoxCtrl.width);

        this.ImgMain.width = this.BoxCtrl.width;
        this.ImgMain.height = this.BoxCtrl.height;
        this.ImgMain.x = 0 
        this.ImgMain.y = 0;
        this.BoxCtrl.y = this.marginTop;
        this.actLoadOver?.();
    }

    private boxCtrlMoveTo(moveX: number, moveY: number) {
        const endX = this.BoxCtrl.x + moveX;
        const endY = this.BoxCtrl.y + moveY;

        // 左右侧限位
        const l = 0;
        const r = this.BoxPanel.width - this.BoxCtrl.width * this.nowScale;
        const t = 0 + this.marginTop;
        const d = this.BoxPanel.height - this.BoxCtrl.height * this.nowScale
        if (endX < l && endX > r) { 
            this.BoxCtrl.x = endX;
        } else if (endX > l) {
            this.BoxCtrl.x = l; 

        } else if (endX < r) {
            this.BoxCtrl.x = r; 
        }
        // 上下侧限位
        if (endY < t && endY > d) {
            this.BoxCtrl.y = endY;
        } else if (endY > t) {
            this.BoxCtrl.y = t;
        } else if (endY < d) {
            this.BoxCtrl.y = d;
        }
    }

    /** 输入图片的X,Y使屏幕中心移动到xy处 */
    public moveTo(x: number, y: number) {
        // 需要移动到的位置
        let endX = -x + this.BoxPanel.width / 2;
        let endY = -y + this.BoxPanel.height / 2;
        // 当前差值
        let offsetX = endX - this.BoxCtrl.x;
        let offsetY = endY - this.BoxCtrl.y;
        // 左右侧限位
        this.boxCtrlMoveTo(offsetX, offsetY)
    }
  

    /**计算两个触摸点之间的距离*/
    private getDistance(points: ReadonlyArray<Readonly<Laya.ITouchInfo>>) {
        let distance = 0;
        if (points && points.length == 2) {
            let dx = points[0].pos.x - points[1].pos.x;
            let dy = points[0].pos.y - points[1].pos.y;

            distance = Math.sqrt(dx * dx + dy * dy);
        }
        return distance;
    }
}

enum ETouchMoveType {
    none,
    move,
    scale
}